<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Weixin {
	var $oauth_authorize = 'https://open.weixin.qq.com/connect/oauth2/authorize';
	var $oauth_access_token = 'https://api.weixin.qq.com/sns/oauth2/access_token';
	var $oauth_refresh_token = 'https://api.weixin.qq.com/sns/oauth2/refresh_token';

	var $user_info_url = 'https://api.weixin.qq.com/sns/userinfo';
	var $check_access_token = 'https://api.weixin.qq.com/sns/auth';

	var $app_id = '';
	var $app_sercret = '';
	var $redirect_uri = '';

	var $code = '';
	var $access_token = '';
	var $refresh_token = '';
	var $expires_in = '';

	var $CI;


	public function __construct($params = array())
	{
		$this->CI =& get_instance();
		if (count($params) > 0)
		{
			$this->initialize($params);
		}

		log_message('debug', "Weixin Class Initialized");
	}

	function initialize($params = array())
	{
		$this->app_id = $params['app_id'];
		$this->app_sercret = $params['app_sercret'];
		$this->redirect_uri = $params['redirect_uri'];
	}

	public function get_authorize_url($scope = 'snsapi_userinfo')
	{
		$state = random_string('sha1');
		$this->CI->session->set_userdata('state', $state);

		$data = array('appid' => $this->app_id,
					  'redirect_uri' => $this->redirect_uri,
					  'response_type' => 'code',
					  'scope' => $scope,
					  'state' => $state);
		$url = $this->oauth_authorize . '?' . http_build_query($data) . '#wechat_redirect';
		return $url;
	}

	public function set_code($code)
	{
		$this->code = $code;
	}

	public function set_token($result = array())
	{
		$this->access_token = $result['access_token'];
		$this->expires_in = $result['expires_in'];
		$this->refresh_token = $result['refresh_token'];
	}

	public function get_token()
	{
		if (empty($this->code)) {
			return array();
		} else {
			$data = array('appid' => $this->app_id,
						  'secret' => $this->app_sercret,
						  'code' => $this->code,
						  'grant_type' => 'authorization_code');

			return $this->get($this->oauth_access_token, $data);
		}
	}

	public function get_user_info($open_id)
	{
		if (!empty($this->access_token)) {
			$data = array('access_token' => $this->access_token,
					  'openid' => $open_id,
					  'lang' => 'zh_CN');
			return $this->get($this->user_info_url, $data);
		} else {
			return array();
		}

	}

	public function refresh()
	{
		$data = array('appid' => $this->app_id,
					  'grant_type' => 'refresh_token',
					  'refresh_token' => $this->refresh_token);
		return $this->get($this->oauth_refresh_token, $data);
	}

	public function check_token($open_id)
	{
		$data = array('access_token' => $this->access_token,
					  'openid' => $open_id);

		$result = $this->get($this->check_access_token, $data);
		if ($result['errcode'] == 0) {
			return TRUE;
		} else {
			return FALSE;
		}
	}

	private function fetch($url, $method='get', $payload = array())
	{
		$ch = curl_init();
		$this_header = array(
			"content-type: application/x-www-form-urlencoded; charset=UTF-8"
		);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $this_header);
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_HEADER, FALSE);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
		if ($method === 'post') {
			curl_setopt($ch, CURLOPT_POST, TRUE);
			curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
		}
		$data = curl_exec($ch);
		curl_close($ch);
		return json_decode($data, true);
	}

	private function get($url, $payload = array())
	{
		$url .= '?';
		$url .= http_build_query($payload);
		$data = $this->fetch($url, 'get');
		return $data;
	}

	private function post($url, $payload = array())
	{
		$data = $this->fetch($url, 'post', $payload);
		return $data;
	}
}
